package xmu.crms.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import xmu.crms.dto.GpsDTO;
import xmu.crms.entity.*;
import xmu.crms.exception.*;
import xmu.crms.mapper.AttendanceMapper;
import xmu.crms.mapper.LocationMapper;
import xmu.crms.mapper.UserMapper;
import xmu.crms.service.*;
import xmu.crms.util.JwtUtil;
import xmu.crms.vo.*;

import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * @author status200
 * @date 2017/11/30
 */
@RestController
public class SeminarController {
    @Autowired
    private GradeService gradeService;
    @Autowired
    private SeminarService seminarService;
    @Autowired
    private SeminarGroupService seminarGroupService;
    @Autowired
    private TopicService topicService;
    @Autowired
    private ClassService classService;
    @Autowired
    private UserService userService;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private LocationMapper locationMapper;
    @Autowired
    private AttendanceMapper attendanceMapper;

    @GetMapping("/seminar/{seminarId}")
    public ResponseEntity<SeminarVO> getSeminar(@PathVariable("seminarId") BigInteger seminarId) throws SeminarNotFoundException{

        Seminar seminar=seminarService.getSeminarBySeminarId(seminarId);
        //这里用于日期格式化输出
        SimpleDateFormat bartDateFormat = new SimpleDateFormat("yyyy-M-d");
        SeminarVO vo = new SeminarVO();

        vo.setId(seminar.getId());
        vo.setName(seminar.getName());
        vo.setDescription(seminar.getDescription());
        vo.setGroupingMethod(seminar.getFixed()==true?"fixed":"random");
        vo.setStartTime(bartDateFormat.format(seminar.getStartTime()));
        vo.setEndTime(bartDateFormat.format(seminar.getEndTime()));

        return new ResponseEntity<>(vo, HttpStatus.OK);
    }


    @GetMapping("/seminar/{seminarId}/my")
    public ResponseEntity<SeminarVO> getMySeminar(@PathVariable("seminarId") BigInteger seminarId,@RequestHeader("Authorization") String authString)throws SeminarNotFoundException,GroupNotFoundException {
        BigInteger userId = JwtUtil.getIdFromAuthString(authString);
        Seminar seminar=seminarService.getSeminarBySeminarId(seminarId);
        SeminarVO vo = new SeminarVO();
        //这里用于日期格式化输出
        SimpleDateFormat bartDateFormat = new SimpleDateFormat("yyyy-M-d");

        vo.setId(seminar.getId());
        vo.setName(seminar.getName());
        vo.setDescription(seminar.getDescription());
        vo.setGroupingMethod(seminar.getFixed()==true?"fixed":"random");
        vo.setStartTime(bartDateFormat.format(seminar.getStartTime()));
        vo.setEndTime(bartDateFormat.format(seminar.getEndTime()));

        //获得seminarGroup就知道是否为组长了
        SeminarGroup seminarGroup=seminarGroupService.getSeminarGroupById(seminarId,userId);
        if(seminarGroup.getLeader()==null){
            vo.setIsLeader(false);
        }else {
            vo.setIsLeader(seminarGroup.getLeader().getId().equals(userId) ? true : false);
        }

        //是否选题
        List<SeminarGroupTopic> seminarGroupTopics=topicService.listSeminarGroupTopicByGroupId(seminarGroup.getId());
        vo.setAreTopicsSelected(seminarGroupTopics.isEmpty()?false:true);

        return new ResponseEntity<>(vo, HttpStatus.OK);
    }

    /**
     * 获得分组信息
     *
     * @param seminarId
     * @param gradeable 是否获取打分状态
     * @return gradeable为true, , 则返回学生可打分的组的列表.
     */
    @GetMapping("/seminar/{seminarId}/group")
    public ResponseEntity<List<GroupVO>> getGroup(@PathVariable("seminarId") BigInteger seminarId,
                                                  @RequestParam(value = "gradeable", required = false) Boolean gradeable,
                                                  @RequestParam(value = "classID", required = false) Integer classId,@RequestHeader("Authorization") String authString)throws SeminarNotFoundException,GroupNotFoundException {
        List<GroupVO> vos = new ArrayList<>();
        BigInteger userId = JwtUtil.getIdFromAuthString(authString);
        if(gradeable){


            //我的seminarGroup和话题
            SeminarGroup mySeminarGroup=seminarGroupService.getSeminarGroupById(seminarId,userId);
            List<SeminarGroupTopic> mine=topicService.listSeminarGroupTopicByGroupId(mySeminarGroup.getId());

            //没选题则直接返回，并报告错误
            if(mine.isEmpty()){
                return  new ResponseEntity<>(vos, HttpStatus.NOT_FOUND);
            }
            Topic mytopic=mine.get(0).getTopic();
            for(SeminarGroup each:seminarGroupService.listSeminarGroupBySeminarId(seminarId)){
                if(classId!=null){
                    if(each.getClassInfo().getId().intValue()!=classId){
                        continue;
                    }
                }
                GroupVO group = new GroupVO();
                group.setId(each.getId());
                try {
                    group.setName(each.getLeader().getName() + "组");
                }catch(Exception e){
                    group.setName("no man's组");
                }
                List<TopicVO> topics = new ArrayList<>();
                for(SeminarGroupTopic s:topicService.listSeminarGroupTopicByGroupId(each.getId())){
                    TopicVO topic=new TopicVO();
                    topic.setId(s.getTopic().getId());
                    topic.setName(s.getTopic().getName());
                    topics.add(topic);
                }
                group.setTopics(topics);
                vos.add(group);
            }

            // 存储topic相同的队伍
            List<GroupVO> sameTopicGroup = new ArrayList<>();

            for(int i=0;i<vos.size();i++){
                if(vos.get(i).getTopics().get(0).getId().equals(mytopic.getId())) {
                    sameTopicGroup.add(vos.get(i));
                }
            }

            //删除跟我的选相同题的队伍
            vos.removeAll(sameTopicGroup);

            //若已经打分，则设置分数，否则设为0
            List<StudentScore> studentScores=gradeService.getStudentScore(seminarId,userId);
            System.out.println(vos.size());
            System.out.println(studentScores.size());
            for(int i=0;i<vos.size();++i){
                SeminarGradeVO temp=new SeminarGradeVO();
                if( studentScores.size()==vos.size())  {
                    temp.setGrade(studentScores.get(i).getGrade());
                }else{
                    temp.setGrade(0);
                }
                vos.get(i).setGrade(temp);
            }

            return new ResponseEntity<>(vos, HttpStatus.OK);
        }else{
            List<SeminarGroup> list=seminarGroupService.listSeminarGroupBySeminarId(seminarId);

            for(SeminarGroup each:seminarGroupService.listSeminarGroupBySeminarId(seminarId)){
                if(classId!=null){
                    if(each.getClassInfo().getId().intValue()!=classId){
                        continue;
                    }
                }
                GroupVO group = new GroupVO();
                group.setId(each.getId());
                try {
                    group.setName(each.getLeader().getName() + "组");
                }catch(Exception e){
                    group.setName("no man's组");
                }
                List<TopicVO> topics = new ArrayList<>();
                for(SeminarGroupTopic s:topicService.listSeminarGroupTopicByGroupId(each.getId())){
                    TopicVO topic=new TopicVO();
                    topic.setId(s.getTopic().getId());
                    topic.setName(s.getTopic().getName());
                    topics.add(topic);
                }
                group.setTopics(topics);
                vos.add(group);
            }
            return new ResponseEntity<>(vos, HttpStatus.OK);
        }
    }

    @GetMapping("/seminar/{seminarId}/group/my")
    public ResponseEntity<GroupVO> getMyGroup(@PathVariable("seminarId") BigInteger seminarId,@RequestHeader("Authorization") String authString) throws GroupNotFoundException{
        BigInteger userId = JwtUtil.getIdFromAuthString(authString);
        SeminarGroup seminarGroup=seminarGroupService.getSeminarGroupById(seminarId,userId);

        GroupVO vo = new GroupVO();
        vo.setId(seminarGroup.getId());
        try {
            vo.setName(seminarGroup.getLeader().getName() + "的小组");
        }catch(Exception e){
            vo.setName("no man的小组");
        }
//leader
        if (seminarGroup.getLeader() != null) {
            StudentVO leader = new StudentVO();
            leader.setId(seminarGroup.getLeader().getId());
            leader.setName(seminarGroup.getLeader().getName());
            vo.setLeader(leader);
        }
//member
        List<StudentVO> members = new ArrayList<>();
        for(User each:seminarGroupService.listSeminarGroupMemberByGroupId(seminarGroup.getId())){
            if(seminarGroup.getLeader()==null||!seminarGroup.getLeader().getId().equals(each.getId()))
            {
                StudentVO student = new StudentVO();
                student.setId(each.getId());
                student.setName(each.getName());
                members.add(student);
            }
        }
        vo.setMembers(members);

        List<TopicVO> topics = new ArrayList<>();
        for(SeminarGroupTopic s:topicService.listSeminarGroupTopicByGroupId(seminarGroup.getId())){
            TopicVO topic=new TopicVO();
            topic.setId(s.getTopic().getId());
            topic.setName(s.getTopic().getName());
            topics.add(topic);
        }
        vo.setTopics(topics);

        return new ResponseEntity<>(vo, HttpStatus.OK);
    }

    @GetMapping("/seminar/{seminarId}/topic")
    public ResponseEntity<List<TopicVO>> getTopics(@PathVariable("seminarId") BigInteger seminarId) {

        List<TopicVO> vos = new ArrayList<>();

        for(Topic each:topicService.listTopicBySeminarId(seminarId)){
            TopicVO topic = new TopicVO();
            topic.setId(each.getId());
            topic.setName(each.getName());
            topic.setDescription(each.getDescription());
            topic.setGroupLimit(each.getGroupNumberLimit());
            topic.setGroupLeft(each.getGroupNumberLimit()-seminarGroupService.listGroupByTopicId(each.getId()).size());
            vos.add(topic);
        }

        return new ResponseEntity<>(vos, HttpStatus.OK);
    }

    @GetMapping("/seminar/{seminarId}/detail")
    public ResponseEntity<SeminarVO> getSeminarDetail(@PathVariable("seminarId") BigInteger seminarId,@RequestHeader("Authorization") String authString)throws SeminarNotFoundException ,CourseNotFoundException,ClassesNotFoundException{
        BigInteger userId = JwtUtil.getIdFromAuthString(authString);

        Seminar seminar=seminarService.getSeminarBySeminarId(seminarId);
        List<ClassInfo> classes=classService.listClassByCourseId(seminar.getCourse().getId());
        //这里用于日期格式化输出
        SimpleDateFormat bartDateFormat = new SimpleDateFormat("yyyy-M-d");
        SeminarVO vo = new SeminarVO();
        vo.setId(seminar.getId());
        vo.setName(seminar.getName());
        vo.setStartTime(bartDateFormat.format(seminar.getStartTime()));
        vo.setEndTime(bartDateFormat.format(seminar.getEndTime()));
        vo.setSite(classes.get(0).getSite());
        vo.setTeacherName(seminar.getCourse().getTeacher().getName());
        vo.setTeacherEmail(seminar.getCourse().getTeacher().getEmail());

        BigInteger classId=new BigInteger("0");
        List<ClassInfo> myclasses=classService.listClassByCourseId(seminar.getCourse().getId());

        for(ClassInfo each:classes) {
            for(ClassInfo every:myclasses){
                if(each.getId().equals(every.getId())){
                    classId=each.getId();
                }
            }
        }
        List<Attendance> attendances=userService.listAttendanceById(classId,seminarId);

        // 获取学生的签到状态
        for (Attendance each : attendances) {
            if (each.getStudent().getId().equals(userId)) {
                int status = each.getAttendanceStatus();
                if (status == 1) {
                    vo.setCallCondition(2);
                }else if(status==2){
                    vo.setCallCondition(0);
                }else if(status==0){
                    vo.setCallCondition(1);
                }else{
                    vo.setCallCondition(1);
                }
            }
        }

        return new ResponseEntity<>(vo, HttpStatus.OK);
    }

    @GetMapping("/seminar/{seminarId}/class/{classId}/attendance")
    public ResponseEntity<SeminarStatusVO> getSeminarAttendanceStatusVO(@PathVariable("seminarId") BigInteger seminarId,@PathVariable("classId") BigInteger classId){
        SeminarStatusVO vo = new SeminarStatusVO();

        Location location= null;
        try {
            location = classService.getCallStatusById(classId,seminarId);
        } catch (SeminarNotFoundException e) {
            vo.setStatus("notstart");
        }
        List<Attendance> attendances= null;
        try {
            attendances = userService.listAttendanceById(classId,seminarId);
        } catch (ClassesNotFoundException e) {
            e.printStackTrace();
        } catch (SeminarNotFoundException e) {
            e.printStackTrace();
        }
        int count=0;
        for(Attendance each:attendances){
            if(each.getAttendanceStatus().equals(0)||each.getAttendanceStatus().equals(1)){
                //正常和迟到
                count++;
            }
        }
        vo.setNumPresent(count);
        vo.setNumStudent(attendances.size());
        if(location != null && location.getStatus() != null) {
            vo.setStatus(location.getStatus() == 0 ? "end" : "calling");
        }

        return new ResponseEntity<SeminarStatusVO>(vo, HttpStatus.OK);
    }

    @GetMapping("/seminar/{seminarId}/class/{classId}/attendance/present")
    public ResponseEntity<List<StudentVO>> getPresentStudents(@PathVariable("seminarId") BigInteger seminarId,
                                                              @PathVariable("classId") BigInteger classId) throws SeminarNotFoundException,ClassesNotFoundException{
        List<StudentVO> vos = new ArrayList<>();
        List<Attendance> attendances=userService.listAttendanceById(classId,seminarId);

        for(Attendance each:attendances){
            if(each.getAttendanceStatus().equals(0)){
                StudentVO student = new StudentVO();
                student.setId(each.getStudent() != null ?each.getStudent().getId() : null);
                student.setName(each.getStudent() != null ? each.getStudent().getName():null);
                vos.add(student);
            }
        }
        return new ResponseEntity<List<StudentVO>>(vos, HttpStatus.OK);
    }

    @GetMapping("/seminar/{seminarId}/class/{classId}/attendance/late")
    public ResponseEntity<List<StudentVO>> getLateStudents(@PathVariable("seminarId") BigInteger seminarId,
                                                           @PathVariable("classId") BigInteger classId) throws SeminarNotFoundException,ClassesNotFoundException{
        List<StudentVO> vos = new ArrayList<>();
        List<Attendance> attendances=userService.listAttendanceById(classId,seminarId);

        for(Attendance each:attendances){
            if(each.getAttendanceStatus().equals(1)){
                StudentVO student = new StudentVO();
                student.setId(each.getStudent() != null? each.getStudent().getId():null);
                student.setName(each.getStudent() != null ? each.getStudent().getName():null);
                vos.add(student);
            }
        }
        return new ResponseEntity<List<StudentVO>>(vos, HttpStatus.OK);
    }

//    @GetMapping("/seminar/{seminarId}/class/{classId}/attendance/my")
//    public ResponseEntity<PresentStatusVO> getMyAttendanceStatus(@PathVariable("seminarId") BigInteger seminarId,
//                                                                 @PathVariable("classId") BigInteger classId,
//                                                                 @RequestHeader("Authorization") String authString) {
//        BigInteger userId = JwtUtil.getIdFromAuthString(authString);
//
//        // 根据学生id,班级id,seminar id查询该学生的签到状态
//        Attendance attendance = userService.getStudentAttendanceByStudentIdAndClassIdAndSeminarId(userId, classId, seminarId);
//
//        PresentStatusVO vo = new PresentStatusVO();
//
//        // 学生未签到
//        if (attendance == null) {
//            vo.setStatus("unset");
//            return ResponseEntity.ok(vo);
//        }
//
//        int status = attendance.getAttendanceStatus();
//
//        // 学生已经签到，设置状态
//        if (status == 1) {
//            vo.setStatus("late");
//        } else if (status == 2) {
//            vo.setStatus("absence");
//        } else if (status == 0) {
//            vo.setStatus("normal");
//        } else {
//            vo.setStatus("abnormal");
//        }
//
//        return ResponseEntity.ok(vo);
//    }

    /**
     * 签到
     *
     * @param classId
     * @param studentId
     * @param dto       请求的gps数据
     * @return
     */
    @PutMapping("/seminar/{seminarId}/class/{classId}/attendance/{studentId}")
    public ResponseEntity<PresentStatusVO> rollCall(@PathVariable("seminarId") BigInteger seminarId,
                                                    @PathVariable("classId") BigInteger classId,
                                                    @PathVariable("studentId") BigInteger studentId,
                                                    @RequestBody GpsDTO dto, @RequestHeader("Authorization") String authString) throws UserNotFoundException, SeminarNotFoundException, ClassesNotFoundException {
        BigInteger userId = JwtUtil.getIdFromAuthString(authString);

        Location location = locationMapper.getLocationByClassIdAndSeminarId(classId, seminarId);

        PresentStatusVO vo = new PresentStatusVO();

        // 没有找到该节课的location,说明还未开始签到
        if(location == null) {
            // 1代表还未开始签到,不能签到
            vo.setStatus(1);
            return ResponseEntity.ok(vo);
        }


        Attendance attendance = userService.getStudentAttendanceByStudentIdAndClassIdAndSeminarId(userId, classId, seminarId);
        // 存在该学生的签到记录，说明已经签到，不能再次签到
        if(attendance != null) {
            // 2代表已经签到,不能再签到
            vo.setStatus(2);
            return ResponseEntity.ok(vo);
        }

        // 设置attendance的class和seminar
        attendance = new Attendance();
        ClassInfo classInfo = new ClassInfo();
        classInfo.setId(classId);
        attendance.setClassInfo(classInfo);
        Seminar seminar = new Seminar();
        seminar.setId(seminarId);
        attendance.setSeminar(seminar);
        User student = new User();
        student.setId(userId);
        attendance.setStudent(student);
        // 当前课堂处于签到状态
        if(location.getStatus().equals(1)) {
            // 设置签到状态为正常
            attendance.setAttendanceStatus(0);
            attendanceMapper.insertAttendance(attendance);
            // 签到成功，且正常签到
            vo.setStatus(3);
            return ResponseEntity.ok(vo);
        } else if (location.getStatus().equals(0)) {
            // 设置签到状态为迟到
            attendance.setAttendanceStatus(1);
            attendanceMapper.insertAttendance(attendance);
            // 签到成功，且迟到
            vo.setStatus(4);
            return ResponseEntity.ok(vo);
        }


        return new ResponseEntity<>(vo, HttpStatus.OK);
    }


    /**
     * 0表示已经评分，1表示还没有评分
     * @param seminarId
     * @param authString
     * @return
     */
    @GetMapping("/seminar/{seminarId}/score/status")
    public ResponseEntity<IdVO> getScoreIdById(@PathVariable("seminarId") BigInteger seminarId,
                                                           @RequestHeader("Authorization") String authString){
        BigInteger userId = JwtUtil.getIdFromAuthString(authString);
        IdVO idVO=new IdVO();
        if(gradeService.hasScoreIdById(seminarId,userId)) {
            idVO.setId(new BigInteger("0"));
        } else{
            idVO.setId(new BigInteger("1"));
        }
        return new ResponseEntity<>(idVO,HttpStatus.OK);
    }

    /**
     * 是否到了打分时间
     * @param seminarId
     * @param authString
     * @return
     */
    @GetMapping("/class/{classId}/seminar/{seminarId}/score/time")
    public ResponseEntity<Integer> getScoreStatus(@PathVariable("seminarId") BigInteger seminarId,
                                                  @PathVariable("classId") BigInteger classId,
                                               @RequestHeader("Authorization") String authString){
        BigInteger userId = JwtUtil.getIdFromAuthString(authString);


        Location location = locationMapper.getLocationByClassIdAndSeminarId(classId,seminarId);
        if(location==null||location.getStatus()!=0){
            return new ResponseEntity<>(1,HttpStatus.NOT_FOUND);
        }
        return new ResponseEntity<>(1,HttpStatus.OK);
    }
}
